import 'dart:convert';
import 'dart:math';

import 'package:app/api/api.dart';
import 'package:app/utils/aes_utils.dart';
import 'package:app/utils/overlay_utils.dart';
import 'package:app/utils/toast_utils.dart';
import "package:dio/dio.dart";

class HttpUtil {
  static final HttpUtil _instance = HttpUtil._internal();
  Dio? _client;

  factory HttpUtil() => _instance;

  HttpUtil._internal() {
    if (null == _client) {
      BaseOptions options = BaseOptions();
      options.baseUrl = Apis.host;
      //options.receiveTimeout = 1000 * 5; //10秒
      //options.connectTimeout = 1000 * 5; //5秒
      _client = Dio(options);
    }
  }

  //https://sc.api.xiaotuzhi.top/sc/banner/getByType/home
  Future<String?> get(String url, [Map<String, dynamic>? params]) async {
    Response<String>? response;
    Map<String, String> headers = {};
    headers.putIfAbsent("clientType", () => "200");
    headers.putIfAbsent(
        "API-Authorization",
        () =>
            "40cc1c575fe13b0ed6c4d63462aa446ddba450f05a54427c074edf5ed9659168");
    if (params != null) {
      response = await _client?.get(url,
          options: Options(headers: headers), queryParameters: params);
    } else {
      response = await _client?.get(url, options: Options(headers: headers));
    }
    return response?.data;
  }

  // async 异步执行，不管这个方法需要多长时间，不会阻塞调用者
  Future<GResponse> post(String url,
      {Map<String, dynamic>? params,
      bool security = true,
      bool decryptedResult = true,
      bool showErrorTips = true,
      bool formData = false}) async {
    if (params != null) {
      //参数需要加密
      if (security) {
        params = {
          "data": aesEncrypt(params),
        };
      }
    }
    Map<String, String> headers = {};
    headers.putIfAbsent("clientType", () => "200");
    GResponse? response;
    Future<Response<dynamic>>? resultFuture;
    if (params != null) {
      if (formData) {
        resultFuture = _client?.post(url,
            options: Options(headers: headers), queryParameters: params);
      } else {
        resultFuture = _client?.post(url,
            options: Options(headers: headers), data: params);
      }
    } else {
      resultFuture = _client?.post(url, options: Options(headers: headers));
    }
    //以同步方式执行异步方法，阻塞直到异步方法返回
    response = await resultFuture
        ?.then((value) => _getResult(value, encoded: decryptedResult))
        .onError((error, stackTrace) {
      GOverlayUtils.endLoading();
      return GResponse(success: false, data: error);
    }).catchError((error) {
      GOverlayUtils.endLoading();
      return GResponse(success: false, data: error);
    });

    // 异常时显示Toast提示
    if (response != null && !response.success && showErrorTips) {
      if (response.data["message"] is String) {
        GTSUtils.showToast(
          response.data["message"],
        );
      }
    }

    return response ?? GResponse(success: false);
  }

  GResponse _getResult(Response<dynamic> response, {bool encoded = true}) {
    GOverlayUtils.endLoading();
    int code = response.data["code"];
    if (code == 200) {
      if (encoded) {
        var data = jsonDecode(aesDecrypted(response.data["data"]));
        return GResponse(data: data);
      } else {
        return GResponse(data: response.data["data"]);
      }
    }
    return GResponse(success: false, data: response.data);
  }
}

class GResponse {
  bool success;
  dynamic data;
  GResponse({this.success = true, this.data});
}
